home *** CD-ROM | disk | FTP | other *** search
- #include "ListBox.h"
-
- #define kScrollBarWidth 16
- #define kItemSize 18 //the vertical size of a cell
- //Change this If you use different sized fonts
-
- #define kDoubleClickTime 25 //Wait time between clicks
-
- //curBox is set to the current listbox before localScoll is called
- //localScroll is called by TrackControl, a macOS call, so I have to
- //use the global to pass information to it...
- ListBox *curBox;
- pascal void localScroll(ControlHandle theControl, short thePart);
-
- ListBox::ListBox() //This just sets everything to nil so we know that it hasn't been preped
- {
- items = nil;
- theScrollBar = nil;
- destDialog = nil;
- SetRect(&destRect,0,0,0,0);
- itemSize.v = itemSize.h = 0;
- topLine = 0;
- curLine = 0;
- lastClick = 0;
- }
-
- ListBox::~ListBox(void)
- {
- Close();
- }
-
- void ListBox::Close(void)
- {
- KillItemList();
- if (theScrollBar != nil)
- DisposeControl(theScrollBar);
- theScrollBar = nil;
- destDialog = nil;
- SetRect(&destRect,0,0,0,0);
- itemSize.v = itemSize.h = 0;
- topLine = 0;
- curLine = 0;
- lastClick = 0;
- }
-
-
-
- void ListBox::SetupFromItem(DialogPtr theDialog, short itemNum)
- {
- short kind;
- Handle dialogItem;
- Rect tempRect;
-
- destDialog = theDialog;
- GetDialogItem(destDialog, itemNum, &kind, &dialogItem, &tempRect);
- SetupFromRect(theDialog, &tempRect);
- }
-
-
- void ListBox::SetupFromRect(DialogPtr theDialog, Rect *rect)
- {
- Rect scrollRect;
-
-
- destRect = *rect;
- scrollRect.top = destRect.top;
- scrollRect.bottom = destRect.bottom;
- scrollRect.left = destRect.right - kScrollBarWidth;
- scrollRect.right = destRect.right;
-
- theScrollBar = NewControl(destDialog, //owningWindow
- &scrollRect, //boundsRect
- "\p", //controlTitle
- true, //initiallyVisible
- 0, //initialValue
- 0, //minimumValue
- 0, //maximumValue
- scrollBarProc, //procID
- nil); //controlReference
- items = nil;
- itemSize.h = destRect.right - destRect.left;
- itemSize.v = kItemSize;
- topLine = 0;
- curLine = 0;
-
- AdjustScrollBar();
- }
-
-
-
- void ListBox::ModalDialog(customModalFilter modalFilter, DialogItemIndex * itemHit)
- {
- EventRecord theEvent;
- short kind;
- Handle dialogItem;
- Rect box;
- Point thePoint;
-
-
- do{
- *itemHit = 0;
- GetNextEvent( everyEvent, &theEvent );
- if (theEvent.what == updateEvt ) {
- BeginUpdate(destDialog);
- SetPort(destDialog);
- DrawDialog(destDialog);
- GetDialogItem(destDialog, 1, &kind, &dialogItem, &box);
- InsetRect(&box, -4, -4);
- PenSize(3, 3);
- FrameRoundRect(&box, 15, 15);
- EndUpdate(destDialog);
- Draw();
- }
- if ( DialogSelect(&theEvent, &destDialog, itemHit) ) {
- if (modalFilter != nil)
- modalFilter(destDialog, &theEvent, itemHit);
- }
- if (TrackEvent(&theEvent)) *itemHit = 1; //TrackEvent returns true if they double click
-
- } while (*itemHit == -1);
-
- }
-
-
- Boolean ListBox::TrackEvent(EventRecord *theEvent)
- {
- Point thePoint;
- Rect boxRect;
- short thePart, vertLoc, newLine;
- ControlActionUPP theAction = NewControlActionProc(localScroll);
- ControlHandle tempControl;
- Boolean doubleClick = false;
-
- if (theEvent->what == mouseDown) {
- SetPort(destDialog);
- thePoint = theEvent->where;
- GlobalToLocal(&thePoint);
- if (PtInRect(thePoint, &destRect)) {
- thePart = FindControl(thePoint, destDialog, &tempControl);
- if ( tempControl == theScrollBar && thePart ) {
- curBox = this;
- switch ( thePart ) {
- case kControlUpButtonPart:
- case kControlDownButtonPart:
- case kControlPageUpPart:
- case kControlPageDownPart:
- thePart = TrackControl(theScrollBar, thePoint, theAction);
- break;
- case kControlIndicatorPart:
- thePart = TrackControl(theScrollBar, thePoint, nil);
- SetTopLine( GetControlValue(theScrollBar) );
- Draw();
- break;
- }
- }
- }
- boxRect = destRect;
- boxRect.right -= kScrollBarWidth;
- if (PtInRect(thePoint, &boxRect) ) {
- vertLoc = thePoint.v - destRect.top;
- newLine = vertLoc / itemSize.v;
- newLine += GetTopLine();
- if (newLine < GetItemCount()) {
- if (newLine == GetCurLine() ) {
- if ( lastClick + kDoubleClickTime > TickCount() )
- doubleClick = true;
- lastClick = TickCount();
- } else
- SetCurLine(newLine);
- }
- }
- }
-
- DisposeRoutineDescriptor(theAction);
- return doubleClick;
- }
-
- void ListBox::SetTopLine(short line)
- {
- topLine = line;
- Draw();
- }
-
- short ListBox::GetTopLine(void)
- {
- return topLine;
- }
-
-
- short ListBox::GetCurLine(void)
- {
- return curLine;
- }
-
- short ListBox::GetCurItem(void)
- {
- short tempLine;
- lbItem *curItem;
-
- curItem = items;
- tempLine = 0;
- while (tempLine != GetCurLine() && curItem != nil) {
- curItem = curItem->next;
- tempLine++;
- }
- return curItem->idNum;
- }
-
- void ListBox::SetCurLine(short line)
- {
- curLine = line;
- Draw();
- }
-
-
- void ListBox::AdjustScrollBar(void)
- {
- short newMax;
- newMax = GetItemCount() - ((destRect.bottom - destRect.top) / itemSize.v);
- if (newMax < 0)
- newMax = 0;
- SetControlMaximum( theScrollBar, newMax);
- SetControlValue( theScrollBar, GetTopLine());
- Draw1Control(theScrollBar);
- }
-
- void ListBox::Draw(void)
- {
- RGBColor white = {0xff, 0xff, 0xff},
- black = {0x00, 0x00, 0x00},
- tempColor;
- short tempLine, bottomLine, charSize, i, selectedLine = GetCurLine();
- lbItem *curItem;
- Point curPoint;
- Rect tempRect;
-
- SetPort(destDialog);
-
- GetForeColor(&tempColor);
-
- tempRect = destRect;
- tempRect.right -= kScrollBarWidth;
- EraseRect(&tempRect);
-
- tempRect.right++;
- PenSize(1,1);
- RGBForeColor(&black);
- FrameRoundRect(&tempRect,1,1);
-
- curItem = items;
- tempLine = 0;
- while (tempLine != GetTopLine() && curItem != nil) {
- curItem = curItem->next;
- tempLine++;
- }
-
- bottomLine = (destRect.bottom - destRect.top) / itemSize.v + GetTopLine();
- while (tempLine < bottomLine && curItem != nil) {
- curPoint.v = (tempLine - GetTopLine() + 1) * itemSize.v + destRect.top - 4;
- curPoint.h = 5 + destRect.left;
- MoveTo(curPoint.h, curPoint.v);
-
- i = 1;
- charSize = kScrollBarWidth;
- while (charSize < itemSize.h && i <= curItem->name[0]) {
- DrawChar(curItem->name[i]);
- charSize += CharWidth(curItem->name[i]);
- i++;
- };
-
-
- if (tempLine == selectedLine) {
- tempRect.top = (tempLine - GetTopLine() ) * itemSize.v + destRect.top + 1;
- tempRect.bottom = (tempLine - GetTopLine() + 1) * itemSize.v + destRect.top - 1;
- tempRect.left = destRect.left + 1;
- tempRect.right = destRect.right - kScrollBarWidth;
- InvertRect(&tempRect);
- }
- tempLine++;
- curItem = curItem->next;
- }
- RGBForeColor(&tempColor);
- Draw1Control(theScrollBar);
- }
-
-
- void ListBox::MakeResTypeList(long resType)
- {
- int resCount, i;
- Str255 name;
- Handle handle;
- short dummyID;
- ResType dummyType;
-
- resCount = Count1Resources(resType);
- for (i = 0; i < resCount; i++) {
- handle = Get1IndResource(resType, i + 1);
- if (handle) {
- GetResInfo(handle, &dummyID, &dummyType, name);
- if (name[0] > 0)
- AddItem(dummyID, name);
- else {
- NumToString(dummyID, &name[0]);
- AddItem(dummyID, name);
- }
- ReleaseResource(handle);
- }
- }
- }
-
-
- void ListBox::AddItem(short idNum, Str255 name)
- {
- lbItem *curItem;
- short i;
-
- if (items == nil) {
- items = (lbItem *) NewPtrClear(sizeof(lbItem));
- curItem = items;
- } else {
- curItem = items;
- while (curItem->next != nil)
- curItem = curItem->next;
-
- curItem->next = (lbItem *)NewPtrClear(sizeof(lbItem));
- curItem = curItem->next;
- }
-
- if (curItem != nil) {
- curItem->idNum = idNum;
- for (i = 0; i < 255; i++)
- curItem->name[i] = name[i];
- curItem->next = nil;
- }
-
- AdjustScrollBar();
- }
-
-
- void ListBox::SwapLines(short line1, short line2)
- {
- short tempLine, i, tempID;
- lbItem *item1, *item2;
- Str255 tempStr;
-
- item1 = items;
- tempLine = 0;
- while (tempLine != line1 && item1 != nil) {
- item1 = item1->next;
- tempLine++;
- }
- item2 = items;
- tempLine = 0;
- while (tempLine != line2 && item2 != nil) {
- item2 = item2->next;
- tempLine++;
- }
-
- if (item1 == nil || item2 == nil)
- return;
-
- for (i=0; i < 255; i++)
- tempStr[i] = item1->name[i];
- for (i=0; i < 255; i++)
- item1->name[i] = item2->name[i];
- for (i=0; i < 255; i++)
- item2->name[i] = tempStr[i];
-
- tempID = item1->idNum;
- item1->idNum = item2->idNum;
- item2->idNum = tempID;
- }
-
-
- void ListBox::KillLine(short num)
- {
- lbItem *curItem, *tempItem;
- short tempLine;
-
- if (items == nil)
- return;
-
- if (num == 0) {
- tempItem = items;
- items = tempItem->next;
- DisposePtr( (Ptr) tempItem);
- } else {
- tempLine = 0;
- curItem = items;
- while (curItem != nil && tempLine != num - 1 ) {
- curItem = curItem->next;
- tempLine++;
- }
-
- if (curItem != nil ) {
- tempItem = curItem->next;
- curItem->next = tempItem->next;
- DisposePtr( (Ptr) tempItem);
- }
- }
- }
-
-
- void ListBox::KillItemList(void)
- {
- lbItem *curItem, *curItem2;
-
- curItem2 = items;
-
- while (curItem2 != nil) {
- curItem = curItem2;
- curItem2 = curItem2->next;
- DisposePtr((Ptr)curItem);
- }
- items = nil;
- }
-
-
- short ListBox::GetItemCount(void)
- {
- short count = 0;
- lbItem *curItem = items;
-
- while (curItem != nil) {
- curItem = curItem->next;
- count++;
- }
- return count;
- }
-
- pascal void localScroll(ControlHandle theControl, short thePart)
- {
- short delta;
- short oldValue;
-
- if ( theControl != curBox->theScrollBar)
- return;
-
- switch ( thePart ) {
- case kControlUpButtonPart:
- delta = -1;break;
- case kControlDownButtonPart:
- delta = 1;break;
- case kControlPageUpPart:
- delta = -5;break;
- case kControlPageDownPart:
- delta = 5;break;
- }
- if ( thePart != 0 ) {
- oldValue = GetControlValue(theControl);
- SetControlValue(theControl , oldValue + delta);
- if (oldValue + delta >= GetControlMaximum(theControl))
- SetControlValue(theControl, GetControlMaximum(theControl));
- if (oldValue + delta <= GetControlMinimum(theControl))
- SetControlValue(theControl, GetControlMinimum(theControl));
- if (oldValue != GetControlValue(theControl)) {
- curBox->SetTopLine( GetControlValue(theControl) );
- curBox->Draw();
- }
- }
- }